<?php
class debug  extends ErrorException {
    protected $code = 0;
    protected $message = '';
    protected $errfile = '';
    protected $errline = '';
    protected $error_handler_function_throw = false;
    protected $errcss = '<meta charset="utf-8"><style>
        ul {margin:5px;}
        li {list-style-type:decimal;}
        .debug_area { border:1px #000 solid;background-color:#EFDFAF;padding-left:10px;}
        .message {color:red;}
        .trace_item{border-bottom:2px #787261 solid;padding:5px;}
        .debug_args{background-color:#FAD5D2;font-size:12px;margin-right:10px;}
        .debug-func{color:blue;}
        .debug_throw{color:#A9291F;font-weight:bold;}
        </style>';
    public function __construct($message, $code =0,$file= 0,$line= 0,$error_handler_function_throw=false) {
        $this->error_handler_function_throw = $error_handler_function_throw;
        $this->message = $message;
        $this->errfile = $file == 0 ? $this->getFile() : $file;
        $this->errline = $line == 0 ? $this->getLine() : $line;
        $this->getErrorType($code);
    }
    public function getErrorType($code) {
        $is_exception = false;
        switch($code) {
            case E_USER_ERROR:
                $type = 'Fatal Error';
                $is_exception = true;
            break;
            case E_USER_WARNING:
            case E_WARNING:
                $type = 'Warning';
            break;
            case E_USER_NOTICE:
            case E_NOTICE:
            case @E_STRICT:
                $type = 'Notice';
            break;
            case @E_RECOVERABLE_ERROR:
                $type = 'Catchable';
            break;
            default:
                $type = 'Framework Level Error';
                $is_exception = true;
            break;
        }
        $this->message = "<b>$type : </b>" . $this->message;
        if($is_exception) {
            //parent :: __construct($this->message,0,$code,$this->getFile(),$this->getLine());
            //parent::__toString();
        } else {
           //$this->__toString();
        }
    }
    public function __toString() {
        $str = $this->errcss;
        $str .='<div class="debug_area">';
        $str .="<div ><span class='message'>{$this->message}</span><ul>";
        $str .="<div class='debug_throw'>Throw Exception in file {$this->errfile} line {$this->errline}</div>";
        $str .= $this->earch($this->getTrace());
        $str .='</ul></div></div>';
        return $str;
    }
    public function earch($traceArr) {
        $str = '';
        foreach($traceArr as $key => $value) {
            if(isset($value['function']) && $value['function'] == 'error2debug') continue;
            $str .= "<li class='trace_item'>" .$this->getInfoStr($value) .'</li>';
        }
        return $str;
    }
    public function getInfoStr($arr) {
        $par = $str = '';
        if(isset($arr['file'])) {
            $str =  " in {$arr['file']} line {$arr['line']};";
        }
        if(!empty($arr['args'])) {
            foreach($arr['args'] as $key=>$value) {
                $par .= '<span class="debug_args">';
                if(is_array($value)) {
                    $par .= print_r($value,true);
                }elseif(is_object($value)) {
                    $par .= get_class($value);
                } else {
                    $par .= "'$value'";
                }
                $par .= '</span>';
                $par .= ',';
            }
            $par = substr($par,0,-1);
        }
        $par .='<b class="debug-func">)</b>';
        $msg = "<b class='debug-func'>";
        $msg .= isset($arr['class']) ? $arr['class'] :'';
        $msg .= isset($arr['type']) ? $arr['type'] :'';
        if($arr['function'] == 'unknown') $arr['function'] = 'Main';
        $msg .= isset($arr['function'])? $arr['function'] .'(': '';
        $msg .= '</b> ';
        return $msg. $par . $str;
    }
}
